
package jwww.handlers;

import java.io.*;
import java.util.Date;

import jwww.service.Page;

/** A page produced by a Service call before headers
    have been produced.
*/
public class BinaryFile
  extends Page
{
  File file = null;
  String filename;
  String error = null;
  long length = 0;

  public BinaryFile(String filename)
  {
    super();
    this.filename = filename;
    date = new Date();
    file = new File(filename);
    status = 200;
    length = file.length();
  }

  /** Generate and cache headers based on constructor info.
   */
  @Override
  public String makeHeaders()
  {
    if (headers != null)
      return headers;

    StringBuilder result = new StringBuilder(1024);
    result.append("HTTP/1.0 " + status + " OK\r\n");
    result.append("Server: JWWW\r\n");
    result.append("Connection: close\r\n");
    if (error == null)
    {
      result.append("Content-Length: " + length + "\r\n");
      result.append("Content-Type: application/octet-stream\r\n");
    }
    else
    {
      result.append("Content-Length: " + error.length() + "\r\n");
      result.append("Content-Type: text/html\r\n");
    }
    result.append("Date: " + rfc822() + "\r\n");

    headers = result.toString();
    return headers;
  }

  public void stream(OutputStream output)
  throws IOException
  {
    long total    = 0;
    long maxchunk = 1024*1024;
    int actual;
    byte[] buffer = new byte[(int)maxchunk];
    BufferedInputStream input = new BufferedInputStream(new FileInputStream(file));
    while (total < length)
    {
      long chunk  = Math.min(maxchunk, length-total);
      actual = input.read(buffer, 0, (int)chunk);
      output.write(buffer, 0, (int)chunk);
      total += actual;
    }
    input.close();
  }
}
